package com.http;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;

/**
 * @author 罗俊华
 * @date 2021/8/27 - 2:26 下午
 */
@Slf4j
public class HttpServer {

    public static void main(String[] args) {

        new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {

                        ch.pipeline().addLast(new LoggingHandler())
                                .addLast(
                                        /**
                                         * Codec 从名称上来说就是包含了编码器与解码器
                                         *  HttpServerCodec extends CombinedChannelDuplexHandler<HttpRequestDecoder, HttpResponseEncoder> implements HttpServerUpgradeHandler.SourceCodec
                                         *  CombinedChannelDuplexHandler 类 组合 了 HttpRequestDecoder，HttpResponseEncoder
                                         *
                                         */
                                        new HttpServerCodec()
                                );


                        /**
                         * SimpleChannelInboundHandler 只关心消息类型是 范型指定的消息
                         */
                        ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
//                                处理请求行、请求头

                                log.debug("收到请求行与请求头：{}", req.uri());

                                DefaultFullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(), HttpResponseStatus.OK);

                                byte[] content = "<h1>早上好</h1>".getBytes(StandardCharsets.UTF_8);
                                response.content().writeBytes(content);

                                response.headers()//.add("content-type","application/json;charset=UTF-8")
                                        .add(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=UTF-8")
                                        .add(HttpHeaderNames.CONTENT_LENGTH, content.length);
                                ch.writeAndFlush(response);

                            }
                        });

                        ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpResponse>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext ctx, HttpResponse msg) throws Exception {
//                              处理请求体
                            }
                        });

                        /* 要自己区分上一步的消息类型

                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {


                                // HttpServerCodec 将请求拆分为两部分，第一部分是 DefaultHttpRequest，包含请求行，请求头
                                // 第二部分是 LastHttpContent ，包含请求体


                                //io.netty.handler.codec.http.DefaultHttpRequest
                                //io.netty.handler.codec.http.LastHttpContent$1
                                log.debug("收到的http消息类型：{}\n{}", msg.getClass(), msg);

                                if (msg instanceof HttpRequest) {
                                    HttpRequest req = (HttpRequest) msg;

                                    // 处理请求行、请求头

                                } else if (msg instanceof HttpResponse) {
                                    HttpResponse resp = (HttpResponse) msg;
//                                            处理请求体
                                }

                                super.channelRead(ctx, msg);
                            }
                        });*/

                    }
                }).bind(80);

    }

}
